﻿using Basic.FlowModel.AuditLogItem;
using Basic.FlowRemoteModel;

namespace Basic.FlowApplication.Model.AuditLog
{
    public enum LogItemChangeType
    {
        None = 0,
        Add = 1,
        Update = 2
    }
    public class AfootAuditLogItem
    {
        public AfootAuditLogItem ()
        {
            this.ChangeType = LogItemChangeType.Add;
            this.PrevNodeStatus = FlowNodeAuditStatus.待开始;
        }
        public AfootAuditLogItem ( AfootAuditLogItem item, LogItemChangeType type )
        {
            this.PrevNodeStatus = FlowNodeAuditStatus.待开始;
            this.ChangeType = type;
            this.CompanyId = item.CompanyId;
            this.EmpByDeptId = item.EmpByDeptId;
            this.EmpByUnitId = item.EmpByUnitId;
            this.BatchNo = item.BatchNo;
            this.EmpId = item.EmpId;
            this.NodeId = item.NodeId;
            this.NextDeptId = item.NextDeptId;
            this.NodeType = item.NodeType;
            this.PrevNodeId = item.PrevNodeId;
            this.PrevBackNo = item.PrevBackNo;
            this.PrtBatchNo = item.PrtBatchNo;
            this.RootBatchNo = item.RootBatchNo;
            this.RootNodeId = item.RootNodeId;
            this.StartTime = item.StartTime;
        }
        public AfootAuditLogItem ( AuditItemInfo item, FlowNodeAuditStatus nodeState )
        {
            this.PrevNodeStatus = nodeState;
            this.ChangeType = LogItemChangeType.None;
            this.Id = item.Id;
            this._Status = item.Status;
            this._AuditState = item.AuditState;
            this._SubFlowState = item.SubFlowState;
            this.BatchNo = item.BatchNo;
            this.CompanyId = item.CompanyId;
            this.EmpByDeptId = item.EmpByDeptId;
            this.EmpByUnitId = item.EmpByUnitId;
            this.NextDeptId = item.NextDeptId;
            this.AuditOpinion = item.AuditOpinion;
            this.MarkState = item.MarkState;
            this.EmpId = item.EmpId;
            this.NodeId = item.NodeId;
            this.NodeType = item.NodeType;
            this.PrevNodeId = item.PrevNodeId;
            this.PrevBackNo = item.PrevBackNo;
            this.PrtBatchNo = item.PrtBatchNo;
            this.RootBatchNo = item.RootBatchNo;
            this.RootNodeId = item.RootNodeId;
            this.OptItemId = item.OptItemId;
            this.StartTime = item.StartTime;
            this.RefreshStatus();
        }

        public AfootAuditLogItem Copy ()
        {
            AfootAuditLogItem item = new AfootAuditLogItem
            {
                _SubFlowState = this._SubFlowState,
                _Status = FlowAuditItemStatus.审核进行中,
                PrevNodeStatus = FlowNodeAuditStatus.待开始,
                ChangeType = LogItemChangeType.Add,
                BatchNo = this.BatchNo,
                CompanyId = this.CompanyId,
                EmpByDeptId = this.EmpByDeptId,
                EmpByUnitId = this.EmpByUnitId,
                EmpId = this.EmpId,
                NodeId = this.NodeId,
                NextDeptId = this.NextDeptId,
                NodeType = this.NodeType,
                PrevNodeId = this.PrevNodeId,
                PrevBackNo = this.PrevBackNo,
                PrtBatchNo = this.PrtBatchNo,
                RootBatchNo = this.RootBatchNo,
                RootNodeId = this.RootNodeId,
                StartTime = this.StartTime,
            };
            if ( this.StartTime.HasValue )
            {
                item.AuditState = this.StartTime >= DateTime.Now ? FlowAuditItemStatus.审核进行中 : FlowAuditItemStatus.待开始;
            }
            else
            {
                item._AuditState = this._AuditState;
            }
            item.RefreshStatus();
            return item;
        }
        /// <summary>
        /// 日志项ID
        /// </summary>
        public long Id
        {
            get;
        }

        /// <summary>
        /// 批次号
        /// </summary>
        public long BatchNo
        {
            get;
            set;
        }
        /// <summary>
        /// 节点ID
        /// </summary>
        public long NodeId { get; set; }

        /// <summary>
        /// 公司ID
        /// </summary>
        public long CompanyId { get; set; }

        /// <summary>
        /// 审核人
        /// </summary>
        public long EmpId { get; set; }

        /// <summary>
        /// 审核人所在单位
        /// </summary>
        public long EmpByUnitId { get; set; }

        /// <summary>
        /// 审核人所在部门
        /// </summary>
        public long EmpByDeptId { get; set; }

        public long? NextDeptId { get; set; }

        private FlowAuditItemStatus _Status = FlowAuditItemStatus.审核进行中;
        /// <summary>
        /// 流程项最终审核状态
        /// </summary>
        public FlowAuditItemStatus Status
        {
            get => this._Status;
            set
            {
                if ( this._Status != value )
                {
                    if ( this.ChangeType == LogItemChangeType.None )
                    {
                        this.ChangeType = LogItemChangeType.Update;
                    }
                    if ( this._Status != FlowAuditItemStatus.审核进行中 )
                    {
                        this.EndTime = DateTime.Now;
                    }
                    this._Status = value;
                    this._RefreshNodeStatus();
                }
            }
        }
        public void RefreshStatus ()
        {
            if ( this._Status == FlowAuditItemStatus.已作废 )
            {
                return;
            }
            else if ( this._AuditState == FlowAuditItemStatus.已撤回 )
            {
                this._Status = FlowAuditItemStatus.已撤回;
                this.NodeStatus = FlowNodeAuditStatus.审核进行中;
            }
            else if ( this._AuditState == FlowAuditItemStatus.审核通过 && this._SubFlowState == FlowSubAuditStatus.审核通过 )
            {
                this._Status = FlowAuditItemStatus.审核通过;
                this.NodeStatus = FlowNodeAuditStatus.审核通过;
            }
            else if ( this._AuditState == FlowAuditItemStatus.审核未通过 || this._SubFlowState == FlowSubAuditStatus.审核未通过 )
            {
                this._Status = FlowAuditItemStatus.审核未通过;
                this.NodeStatus = FlowNodeAuditStatus.审核未通过;
            }
            else if ( this._AuditState == FlowAuditItemStatus.审核通过 && this._SubFlowState == FlowSubAuditStatus.审核进行中 )
            {
                this._Status = FlowAuditItemStatus.审核进行中;
                this.NodeStatus = FlowNodeAuditStatus.审核进行中;
            }
            else if ( this._AuditState == FlowAuditItemStatus.终审通过 )
            {
                this._Status = this._AuditState;
                this.NodeStatus = FlowNodeAuditStatus.终审通过;
            }
            else if ( this._AuditState == FlowAuditItemStatus.审核进行中 )
            {
                this._Status = this._AuditState;
                this.NodeStatus = FlowNodeAuditStatus.审核进行中;
            }
            else if ( this._AuditState == FlowAuditItemStatus.已取消 )
            {
                this._Status = this._AuditState;
                this.NodeStatus = FlowNodeAuditStatus.已取消;
            }
            else if ( this._AuditState == FlowAuditItemStatus.已转办 ||
                this._AuditState == FlowAuditItemStatus.已委托 ||
                this._AuditState == FlowAuditItemStatus.已向前加签 ||
                this._AuditState == FlowAuditItemStatus.已向后加签 )
            {
                this._Status = this._AuditState;
                this.NodeStatus = FlowNodeAuditStatus.审核进行中;
            }
            else
            {
                this._Status = this._AuditState;
                this.NodeStatus = FlowNodeAuditStatus.待开始;
            }
            if ( this.EndTime.HasValue == false && this.NodeStatus != FlowNodeAuditStatus.待开始 && this.NodeStatus != FlowNodeAuditStatus.审核进行中 )
            {
                this.EndTime = DateTime.Now;
            }
        }
        private void _RefreshNodeStatus ()
        {
            if ( this._Status == FlowAuditItemStatus.终审通过 )
            {
                this.NodeStatus = FlowNodeAuditStatus.终审通过;
            }
            else if ( this._Status == FlowAuditItemStatus.已转办 ||
              this._Status == FlowAuditItemStatus.已委托 ||
              this._Status == FlowAuditItemStatus.已向前加签 ||
              this._Status == FlowAuditItemStatus.已向后加签 )
            {
                this.NodeStatus = FlowNodeAuditStatus.审核进行中;
            }
            else if ( this._Status == FlowAuditItemStatus.已撤回 || this._Status == FlowAuditItemStatus.打回修改 || this._Status == FlowAuditItemStatus.已回退 || this._Status == FlowAuditItemStatus.已作废 )
            {
                this.NodeStatus = FlowNodeAuditStatus.待开始;
            }
            else if ( this._Status == FlowAuditItemStatus.审核通过 )
            {
                this.NodeStatus = FlowNodeAuditStatus.审核通过;
            }
            else if ( this._Status == FlowAuditItemStatus.审核未通过 )
            {
                this.NodeStatus = FlowNodeAuditStatus.审核未通过;
            }
            else if ( this._Status != FlowAuditItemStatus.审核进行中 )
            {
                this.NodeStatus = FlowNodeAuditStatus.审核进行中;
            }
            else if ( this._Status != FlowAuditItemStatus.已取消 )
            {
                this.NodeStatus = FlowNodeAuditStatus.已取消;
            }
        }
        private FlowSubAuditStatus _SubFlowState = FlowSubAuditStatus.审核进行中;
        /// <summary>
        /// 子流程审核状态
        /// </summary>
        public FlowSubAuditStatus SubFlowState
        {
            get => this._SubFlowState;
            set
            {
                if ( this._SubFlowState != value )
                {
                    if ( this.ChangeType == LogItemChangeType.None )
                    {
                        this.ChangeType = LogItemChangeType.Update;
                    }
                    this._SubFlowState = value;
                    this.RefreshStatus();
                }
            }
        }
        private FlowAuditItemStatus _AuditState = FlowAuditItemStatus.审核进行中;
        /// <summary>
        /// 用户审核状态
        /// </summary>
        public FlowAuditItemStatus AuditState
        {
            get => this._AuditState;
            set
            {
                if ( this._AuditState != value )
                {
                    if ( this.ChangeType == LogItemChangeType.None )
                    {
                        this.ChangeType = LogItemChangeType.Update;
                    }
                    this._AuditState = value;
                    this.RefreshStatus();
                }
            }
        }
        public FlowNodeAuditStatus PrevNodeStatus
        {
            get;
            private set;
        } = FlowNodeAuditStatus.审核进行中;
        public FlowNodeAuditStatus NodeStatus
        {
            get;
            set;
        } = FlowNodeAuditStatus.审核进行中;
        /// <summary>
        /// 结束日期
        /// </summary>
        public DateTime? EndTime { get; private set; }

        /// <summary>
        /// 超时时间
        /// </summary>
        public DateTime? TimeOut { get; set; }

        /// <summary>
        /// 审批意见
        /// </summary>
        public string AuditOpinion { get; set; }

        /// <summary>
        /// 回退的节点ID
        /// </summary>
        public long? BackNodeId { get; set; }

        /// <summary>
        /// 上一个节点ID
        /// </summary>
        public long? PrevNodeId { get; set; }

        /// <summary>
        /// 上一个批次号
        /// </summary>
        public long? PrevBackNo { get; set; }

        /// <summary>
        /// 发起根节点ID
        /// </summary>
        public long RootNodeId { get; set; }

        /// <summary>
        /// 循环审批时父批次号
        /// </summary>
        public long? PrtBatchNo { get; set; }

        /// <summary>
        /// 根批次号指子节点的开始节点或开始节点的批次号
        /// </summary>
        public long? RootBatchNo { get; set; }
        public LogItemChangeType ChangeType { get; private set; } = LogItemChangeType.None;
        public FlowNodeType NodeType { get; set; }
        /// <summary>
        /// 审批项标记状态 主要指当前项 上级发起方式
        /// </summary>
        public FlowItemMarkState MarkState { get; set; }
        /// <summary>
        /// 抄送人
        /// </summary>
        public long[] CopyId { get; set; }
        public long? SignFileId { get; set; }
        /// <summary>
        /// 委托，加签和指派的审批项ID
        /// </summary>
        public long? OptItemId { get; set; }

        public DateTime? StartTime { get; set; }
    }
}
